package cn.summit.tools;


import cn.summit.exception.ArgsInvalidException;
import cn.summit.validation.dto.ValidError;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.util.CollectionUtils;

import javax.annotation.PostConstruct;
import javax.validation.ConstraintViolation;
import javax.validation.Validator;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 序列号工具类
 *
 * @author zj
 */
@Slf4j
@Configuration
public class ValidateUtils {

    /**
     * 服务对象
     */
    @Autowired
    protected Validator validator;

    private static ValidateUtils validateUtils;

    @PostConstruct
    public void init() {
        validateUtils = this;
    }

    /**
     * 参数校验
     */
    public static <T> void validate(List<T> list, Class<?>... groups) throws ArgsInvalidException {
        if (CollectionUtils.isEmpty(list)) {
            throw new ArgsInvalidException("参数不能为空");
        }
        for (int i = 0; i < list.size(); i++) {
            T t = list.get(i);
            Set<ConstraintViolation<T>> violations = validateUtils.validator.validate(t, groups);
            if (violations.size() > 0) {
                List<ValidError> errors = new ArrayList<>();
                for (ConstraintViolation<T> violation : violations) {
                    errors.add(new ValidError(violation.getPropertyPath().toString(),
                        violation.getMessage() + "[当前值:" + violation.getInvalidValue() + "]"));
                }
                throw new ArgsInvalidException("第" + (i + 1) + "行参数校验失败", errors);
            }
        }
    }

    /**
     * 参数校验
     */
    public static <T> void validate(T t, Class<?>... groups) throws ArgsInvalidException {
        validate(t, "参数校验失败", groups);
    }

    /**
     * 参数校验
     */
    public static <T> void validate(T t, String defaultMsg, Class<?>... groups)
        throws ArgsInvalidException {
        Set<ConstraintViolation<T>> violations = validateUtils.validator.validate(t, groups);
        if (violations.size() > 0) {
            List<ValidError> errors = new ArrayList<>();
            for (ConstraintViolation<T> violation : violations) {
                errors.add(new ValidError(violation.getPropertyPath().toString(),
                    violation.getMessage() + "[当前值:" + violation.getInvalidValue() + "]"));
            }
            log.error(errors.stream().map(msg -> msg.getElement() + msg.getMessage())
                .collect(Collectors.joining(";")));
            throw new ArgsInvalidException(defaultMsg, errors);
        }
    }

    /**
     * excel参数校验
     */
    public static <T> void excelImportValidate(List<T> list, Class<?>... groups)
        throws ArgsInvalidException {
        if (CollectionUtils.isEmpty(list)) {
            throw new ArgsInvalidException("参数不能为空");
        }
        List<ValidError> errorList = new ArrayList<>();

        for (int i = 0; i < list.size(); i++) {
            T t = list.get(i);
            Set<ConstraintViolation<T>> violations = validateUtils.validator.validate(t, groups);
            if (violations.size() > 0) {
                StringBuilder sb = new StringBuilder();
                for (ConstraintViolation<T> violation : violations) {
                    sb.append(violation.getPropertyPath().toString()).append(violation.getMessage())
                        .append("[当前值:").append(violation.getInvalidValue()).append("];");
                }
                errorList.add(new ValidError("excel第" + (i + 2) + "行", sb.toString()));
            }
        }
        if (errorList.size() > 0) {
            throw new ArgsInvalidException("模板格式不符合要求", errorList);
        }
    }

}